#include "dbcontroler.h"
#include <QSqlDatabase>
#include <QMessageBox>
#include <QSqlQuery>
#include <QDebug>
#include <QSqlError>
#include <QSqlRecord>
#include <QVariant>
#include "qcoreapplication.h"
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
std::shared_ptr<DBControler> DBControler::DBMaster=nullptr;
QMutex DBControler::mutex;
DBControler::DBControler(QObject *parent) : QObject(parent)
{
    db=QSqlDatabase::addDatabase("QSQLITE");
}

DBControler::~DBControler()
{
    _disconnect();
}

std::shared_ptr<DBControler> DBControler::get_instance()
{
    if(DBMaster==nullptr){
        QMutexLocker locker(&mutex);
        if(DBMaster==nullptr){
            DBMaster = std::shared_ptr<DBControler>(new DBControler());
        }
    }
    return DBMaster;
}

int DBControler::_connect()
{
    if(db.isOpen()) return 1;
    if(!db.open()){
        QMessageBox::critical(NULL,"数据库","打开失败");
        return 0;
    }
    return 1;
}

int DBControler::_config()
{
    db.setHostName("localhost");
    db.setDatabaseName(".\\CloudUser.db");
    if(_connect()) return 1;
    return 0;
}

int DBControler::_disconnect()
{
    qDebug()<<__FILE__<<__LINE__<<"Boom";
    if(db.isOpen()){
        db.close();
        return 0;
    }
    return 1;
}

bool DBControler::_RegisterUser(const char *_UserName, const char *_Pwd)
{
    _config();
    if(!db.isOpen()){
        return false;
    }
    QSqlQuery query;
    QString Un=QString(_UserName);
    QString Pd=QString(_Pwd);
    QString exec=QString("insert into "
                         "UserInfo(UserName,Pwd,onlineStatus) "
                         "values('%1','%2',%3)")
            .arg(Un)
            .arg(Pd)
            .arg(QString::number(0));


    //qDebug()<<exec;
    return query.exec(exec);
}
bool DBControler::_LoginUser(const char *_UserName, const char *_Pwd,QMap<QString,QVariant>&GetInfo)
{
    _config();
    if(!db.isOpen()){
        return false;
    }

    //QMap<QString,QVariant> GetInfo;
    QSqlQuery query;
    QString Un=QString(_UserName);
    QString Pd=QString(_Pwd);
    QString exec=QString("select * "
                         "from UserInfo "
                         "where UserName='%1' AND Pwd='%2'")
            .arg(Un)
            .arg(Pd);


    //qDebug()<<exec;
    query.exec(exec);
    QSqlRecord Record=query.record();
    int RecordSize=Record.count();
    if(query.next()){
        for(int i=0;i<RecordSize;i++){
            GetInfo.insert(Record.fieldName(i),query.value(i));
        }
    }
    // qDebug()<<GetInfo["onlineStatus"].value<qlonglong>();
    if(GetInfo.size()){
        if(GetInfo["onlineStatus"].value<qlonglong>()==1){
            GetInfo.clear();
        }
        else{
            _UpDateOnlineStatus(_UserName,1);
            GetInfo["onlineStatus"]=1;
        }
    }
    return true;
}

bool DBControler::_UpDateOnlineStatus(const char* _UserName,int _Status)
{
    _config();
    if(!db.isOpen()){
        return false;
    }
    QString Un=QString(_UserName);
    QString Status=QString(QString::number(_Status));
    QString exec=QString("update UserInfo "
                         "set onlineStatus = %1 "
                         "where UserName='%2'")
            .arg(Status)
            .arg(Un);

    QSqlQuery query;
    if(!query.exec(exec))return false;
    return true;

}

bool DBControler::_DownloadUpdate(const char *_UserName)
{
    return _UpDateOnlineStatus(_UserName,0);
}

bool DBControler::SearchOnline(const char * _UserName,QList<QPair<QString, QString>>&info)
{
    _config();
    QString Un=QString(_UserName);
    //QList<QPair<QString,QString>>result;
    if(!db.isOpen()){
        return false;
    }
    QString exec=QString("select UserName,etc "
                         "from UserInfo "
                         "where onlineStatus=1 AND UserName!='%1'")
            .arg(Un);

    QSqlQuery query;
    query.exec(exec);
    while(query.next()){
        info.append({query.value(0).value<QString>(),query.value(1).value<QString>()});
    }
    return true;
}



QList<QPair<QString, QString>> DBControler::_AllNetScanUser(const char *_UserName)
{
    _config();
    if(!db.isOpen())return{};
    QList<QPair<QString,QString>>result;
    QString ScanName=QString(_UserName);
    QSqlQuery query;
    QString exec=QString("select UserName,etc "
                         "from UserInfo "
                         "where UserName='%1'").arg(ScanName);
    if(!query.exec(exec)){
        qDebug()<<__FILE__<<__LINE__<<"执行失败";
        return {};
    }
    while (query.next()) {
        result.append({query.value(0).value<QString>(),
                       query.value(1).value<QString>()});
    }
    return result;
}

bool DBControler::_SetFriendRequestInfo(QString SenderName, QString RecvName, int status)
{
    _config();
    if(!db.isOpen())return false;

    if(_isFriend(SenderName,RecvName)) return false;
    QString exec=QString("insert into "
                         "FriendRequest(SenderId,ReceiverId,RequestStatus) "
                         "values('%1','%2',%3)")
            .arg(SenderName)
            .arg(RecvName)
            .arg(QString::number(status));


    QSqlQuery query;
    if(!query.exec(exec)){
        return false;
    }
    return true;

}

QList<QMap<QString,QVariant>> DBControler::_PullFriendRequest(QString UserName)
{
    _config();
    if(!db.isOpen())return{};
    QString exec=QString("select * "
                         "from FriendRequest "
                         "where ReceiverId='%1'")
            .arg(UserName);
    QSqlQuery query;
    if(!query.exec(exec)){
        return{};
    }
    QList<QMap<QString,QVariant>> ret;
    while (query.next()) {
        QMap<QString,QVariant> Ainfo;
        Ainfo["SenderId"]=query.value(1);
        Ainfo["RequestStatus"]=query.value(3);
        Ainfo["CreateTime"]=query.value(5);
        ret.append(Ainfo);
    }
    return ret;
}

bool DBControler::_MakeFriend(QString User1, QString User2, int Status, QString Info)
{

    UpfriendRequestTableStatus(User1,User2,Status);
    _config();
    if(!db.isOpen())return false;
    QJsonDocument doc=QJsonDocument::fromJson(Info.toUtf8());

    if(Status==FRIEND_REQUEST_STATUS_AGREE){
        QString exc1=QString("insert into friends(user_id,friend_id) "
                            "values('%1','%2');")
                .arg(User1)
                .arg(User2);
        QString exc2=QString("insert into friends(user_id,friend_id) "
                            "values('%1','%2');")
                .arg(User2)
                .arg(User1);
        QSqlQuery query;
        if(!query.exec(exc1)||!query.exec(exc2))return false;
    }
    return true;
}

bool DBControler::UpfriendRequestTableStatus(QString User1, QString User2, int Status)
{
    _config();
    if(!db.isOpen()){
        return false;
    }


    QString exec=QString("update FriendRequest "
                         "set RequestStatus=%1 "
                         "where SenderId='%2' AND ReceiverId='%3'")
            .arg(QString::number(Status))
            .arg(User1)
            .arg(User2);

    QSqlQuery query;

    if(!query.exec(exec))return false;

    return true;
}

bool DBControler::getUserEtc(QString User, QString & Value)
{
    _config();
    if(!db.isOpen()){
        return false;
    }
    QString exc=QString("select etc from UserInfo "
                        "where UserName='%1'").arg(User);
    QSqlQuery query;
    if(!query.exec(exc))return false;
    if(!query.next())return false;
    Value=query.value(0).value<QString>();
    return true;
}

bool DBControler::_isFriend(QString User1, QString User2)
{
    _config();
    if(!db.isOpen()){
        return true;
    }
    QString exc=QString("select * from friends "
                        "where user_id='%1' AND friend_id='%2' AND is_active=1")
            .arg(User1)
            .arg(User2);
    QSqlQuery query;
    if(!query.exec(exc)){
        return true;
    }
    if(!query.next()){
        return false;
    }
    return true;
}

bool DBControler::_PullFriendList(QString User, QJsonArray &Info)
{
    _config();
    if(!db.isOpen())return false;
    QString exc=QString("select * from friends "
                        "where user_id='%1'")
            .arg(User);
    QSqlQuery query;
    if(!query.exec(exc))return false;

    while(query.next()){
        QJsonObject Ainf;
        Ainf["FID"]=query.value(1).value<QString>();
        Ainf["RELATE"]=query.value(5).value<int>();
        Ainf["STATUS"]=query.value(4).value<int>();
        Info.push_back(Ainf);
    }
    return true;
}

void DBControler::distroy_instance()
{
}
